package Modelo;

import java.io.Serializable;

abstract public class Nodo implements Serializable
{
	private static final long serialVersionUID = 2639188916677679403L;

	public static final int NORMAL = 0, FACTORIAL = 1, PERCENTAGEM = 2, RAIZ_QUADRADA = 3;
	
	/*Nodo pai deste nodo, tamb�m conhecido como nodo anterior.
	 * Se null, significa que � o topo da arvore.*/
	private Nodo pai;
	
	/*Filhos deste nodo, ou os proximos nodos. 
	 * Se ambos forem null, significa que o nodo � a raiz da arvore.
	 * Posi��o 0 � para a esquerda e a posi��o 1 � para a direita.*/
	private Nodo[] filhos;
	
	private int especial;
	
	private Nodo percVal;
	
	/*Construtor por omiss�o. Inicializa o topo da arvore.*/
	public Nodo()
	{
		pai = null;
		
		especial = 0;
		
		percVal = null;
		
		inicializaFilhos();
	}
	
	/*Construtor que recebe uma flag de especialidade.*/
	public Nodo(int espc)
	{
		pai = null;
		
		especial = espc;
		
		percVal = null;
		
		inicializaFilhos();
	} 
	
	/*Inicializa um nodo da arvore.*/
	public Nodo(Nodo pai)
	{
		this.pai = pai;
		
		especial = 0;
		
		inicializaFilhos();
	}
	
	/*Define o pai deste nodo.*/
	public void setPai(Nodo pai)
	{
		this.pai = pai;
	}
	
	/*Devolve o pai deste nodo.*/
	public Nodo getPai()
	{
		return pai;
	}
	
	/*Define o filho deste nodo. Direita = 1, Esquerda = 0*/
	public void setFilho(Nodo filho, int i)
	{
		filhos[i] = filho;
		
		filho.setPai(this);
	}
	
	/*Devolve o filho deste nodo. Direita = 1, Esquerda = 0*/
	public Nodo getFilho(int i)
	{
		return filhos[i];
	}
	
	/*Inicializa os filhos do nodo.*/
	private void inicializaFilhos()
	{
		filhos = new Nodo[2];
		filhos[0] = null; filhos[1] = null;
	}
	
	/*Define o nodo que cont�m o valor a ser utilizado na percentagem.*/
	public void setPercVal(Nodo percVal)
	{
		this.percVal = percVal;
	}
	
	/*Devolve o nodo que cont�m o valor da percentagem.*/
	public Nodo getPercVal()
	{
		return percVal;
	}
	
	/*Devolve a flag que determina a especialidade do nodo.*/
	public int isEspecial()
	{
		return especial;
	}
	
	public void setEspecial(int flag)
	{
		if(flag < 0 || flag > 3)
			return;
		
		especial = flag;
	}

	/*Devolve operador. Importante se nodo = Operador.*/
	abstract String getOperador();
	
	/*Devolve o nome da variavel. Importante se Nodo = Variavel.*/
    abstract String getVarNome();
	
    /*Devolve um valor. Importante se Nodo = Operando e Variavel.*/
	abstract double getValor();
	
	/*Define um valor. Importante se Nodo = Operando. e Variavel*/
	abstract void setValor(double valor);
}
